package com.example.app;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

/**
 * Simple INI reader for INSTALLDIR\\config.ini written by MSI.
 * Reads from section [app] and returns value for the requested key.
 */
public class ConfigReader {
    private static final Logger log = LogManager.getLogger(ConfigReader.class);
    private static final String SECTION = "app";

    /**
     * Read value for a key from INSTALLDIR\\config.ini (section [app]).
     * Returns null if file or key not found.
     */
    public static String readConfig(String key) {
        Path configPath = locateConfigIni();
        if (configPath == null || !Files.exists(configPath)) {
            System.err.println("ConfigReader: config.ini not found at " + configPath);
            return null;
        }
        return readIniValue(configPath, SECTION, key);
    }

    public static Path locateConfigIni() {
        // 1) Try current working directory (common for jpackage exe launchers)
        Path cwd = Paths.get(System.getProperty("user.dir"));
        Path iniInCwd = cwd.resolve("config.ini");
        log.info("ConfigReader: current working directory: " + iniInCwd);
        if (Files.exists(iniInCwd)) return iniInCwd;

        // 2) Try alongside the launcher/jar location: <INSTALLDIR>/app/*.jar -> go up one
        try {
            Path codeSource = Paths.get(ConfigReader.class.getProtectionDomain()
                    .getCodeSource().getLocation().toURI());
            // If running from jar or classes, codeSource could be .../app/*.jar or .../target/classes
            Path baseDir = codeSource.getParent();
            if (baseDir != null) {
                // For jpackage layout, jars live in INSTALLDIR/app; go up one to INSTALLDIR
                Path installDir = baseDir.getParent() != null ? baseDir.getParent() : baseDir;
                Path iniInInstall = installDir.resolve("config.ini");
                if (Files.exists(iniInInstall)) return iniInInstall;
            }
        } catch (URISyntaxException ignored) {
        }

        // 3) Fallback: try LocalAppData or ProgramFiles style app dir names if known
        // Not strictly needed; MSI writes to INSTALLDIR and steps above cover common runtime layouts.

        return null;
    }

    private static String readIniValue(Path iniPath, String section, String key) {
        try (BufferedReader br = Files.newBufferedReader(iniPath, StandardCharsets.UTF_8)) {
            boolean inSection = false;
            String line;
            while ((line = br.readLine()) != null) {
                line = line.trim();
                if (line.isEmpty() || line.startsWith(";") || line.startsWith("#")) {
                    continue;
                }
                // Section header
                if (line.startsWith("[") && line.endsWith("]")) {
                    String secName = line.substring(1, line.length() - 1).trim();
                    inSection = section.equalsIgnoreCase(secName);
                    continue;
                }
                if (inSection) {
                    int idx = line.indexOf('=');
                    if (idx > 0) {
                        String k = line.substring(0, idx).trim();
                        if (key.equalsIgnoreCase(k)) {
                            String value = line.substring(idx + 1).trim();
                            // Remove optional surrounding quotes
                            if (value.startsWith("\"") && value.endsWith("\"") && value.length() >= 2) {
                                value = value.substring(1, value.length() - 1);
                            }
                            return value;
                        }
                    }
                }
            }
        } catch (IOException e) {
            System.err.println("ConfigReader: failed reading ini: " + iniPath + ", error=" + e.getMessage());
        }
        return null;
    }
}